using System.Collections.Generic;
using System.Linq;
using System.Web;
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Navigation.Models;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Localization.Services;
using Orchard.UI.Navigation;

namespace Orchard.CulturePicker.Services {
    [UsedImplicitly]
    [OrchardFeature("Orchard.CulturePicker.MainMenu")]
    [OrchardSuppressDependency("Orchard.Core.Navigation.Services.MainMenuNavigationProvider")]
    public class LocalizableMainMenuNavigationProvider : INavigationProvider {
        private readonly IContentManager _contentManager;
        private readonly ICultureManager _cultureManager;
        private readonly IWorkContextAccessor _workContextAccessor;

        public LocalizableMainMenuNavigationProvider(IContentManager contentManager, ICultureManager cultureManager, IWorkContextAccessor workContextAccessor) {
            _contentManager = contentManager;
            _cultureManager = cultureManager;
            _workContextAccessor = workContextAccessor;
        }

        #region INavigationProvider Members

        public string MenuName {
            get { return "main"; }
        }

        public void GetNavigation(NavigationBuilder builder) {
            IEnumerable<MenuPart> menuParts = _contentManager.Query<MenuPart, MenuPartRecord>().Where(x => x.OnMainMenu).WithQueryHints(new QueryHints().ExpandRecords<MenuItemPartRecord>()).List();
            menuParts = FilterForCurrentCulture(menuParts);

            foreach (MenuPart menuPart in menuParts) {
                if (menuPart != null) {
                    MenuPart part = menuPart;

                    if (part.Is<MenuItemPart>()) {
                        builder.Add(new LocalizedString(HttpUtility.HtmlEncode(part.MenuText)), part.MenuPosition, item => item.Url(part.As<MenuItemPart>().Url));
                    }
                    else {
                        builder.Add(new LocalizedString(HttpUtility.HtmlEncode(part.MenuText)), part.MenuPosition, item => item.Action(_contentManager.GetItemMetadata(part.ContentItem).DisplayRouteValues));
                    }
                }
            }
        }

        #endregion

        #region Helpers

        // Filters menu items for current culture
        private IEnumerable<MenuPart> FilterForCurrentCulture(IEnumerable<MenuPart> items) {
            string currentCulture = _cultureManager.GetCurrentCulture(_workContextAccessor.GetContext().HttpContext);

            foreach (MenuPart item in items) {
                var localizationPart = item.ContentItem.Parts.FirstOrDefault(p => p is ILocalizableAspect).As<ILocalizableAspect>();
                if (localizationPart == null
                    || localizationPart.Culture == null
                    || localizationPart.Culture == currentCulture) {
                    yield return item;
                }
            }
        }

        #endregion
    }
}